/**
 *  Copyright [2011] Steffen Kämpke
 *  mailto: steffen.kaempke@pennychecker.de
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.pennychecker.example.mvp.presenter;

import com.google.inject.Inject;
import com.pennychecker.example.mvp.model.User;
import com.pennychecker.example.action.FetchUsers;
import com.pennychecker.example.action.FetchUsersResult;
import com.pennychecker.example.mvp.event.EditUserEvent;
import com.pennychecker.example.mvp.event.NewUserEvent;
import com.pennychecker.example.mvp.event.NewUserEventHandler;
import com.pennychecker.swing.mvp.SwingDisplay;
import com.pennychecker.swing.mvp.SwingPresenter;
import com.pennychecker.swing.mvp.event.EventBus;
import com.pennychecker.swing.presenter.ext.event.ClickEvent;
import com.pennychecker.swing.presenter.ext.event.ClickHandler;
import com.pennychecker.swing.presenter.ext.event.DoubleClickEvent;
import com.pennychecker.swing.presenter.ext.event.DoubleClickHandler;
import com.pennychecker.swing.presenter.ext.event.HasClickHandlers;
import com.pennychecker.swing.presenter.ext.event.HasDoubleClickHandlers;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.customware.gwt.dispatch.client.ActionCallback;
import net.customware.gwt.dispatch.client.DispatchAsync;

/**
 *
 * @author Steffen Kämpke mailto:steffen.kaempke@pennychecker.de
 */
public final class AllUserPresenter extends SwingPresenter<AllUserPresenter.Display> {

    private final DispatchAsync dispatch;
    private final List<User> users = new ArrayList<User>();

    /**
     * 
     * @param display
     * @param eventBus
     * @param dispatch 
     */
    @Inject
    public AllUserPresenter(Display display, EventBus eventBus, DispatchAsync dispatch) {
        super(display, eventBus);
        this.dispatch = dispatch;
        bind();
        fetchUsers();
    }

    @Override
    protected void onBind() {
        registerHandler(display.getUserListClick().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent ce) {
                int index = display.getSelectedUserIndex();
                if (index < 0) {
                    return;
                }
                final User selectedUser = users.get(index);
                display.setSelectedUser(selectedUser);
            }
        }));

        registerHandler(display.getUserListDoubleClick().addDoubleClickHandler(new DoubleClickHandler() {

            public void onDoubleClick(DoubleClickEvent dce) {
                int index = display.getSelectedUserIndex();
                if (index < 0) {
                    return;
                }
                final User selectedUser = users.get(index);
                display.setSelectedUser(selectedUser);

                eventBus.fireEvent(new EditUserEvent(selectedUser));
            }
        }));

        registerHandler(eventBus.addHandler(NewUserEvent.TYPE, new NewUserEventHandler() {

            public void onNewUserEvent(NewUserEvent event) {

                final User newUser = event.getUser();
                assert null != newUser;

                int index = users.indexOf(newUser);
                
                if ( index == -1) {
                    users.add(newUser);
                } else {
                    users.set(index,newUser);
                }
                
                
                display.setUsers(users);
                display.setSelectedUser(newUser);

                display.setSelection(index);
            }
        }));

        registerHandler(display.getAddUserButton().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent ce) {
                eventBus.fireEvent(new EditUserEvent(null));
            }
        }));
    }

    @Override
    protected void onUnbind() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void refreshDisplay() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    private void fetchUsers() {
        dispatch.execute(new FetchUsers(), new ActionCallback<FetchUsersResult>() {

            public void onFailure(Throwable caught) {
                Logger.getLogger(AllUserPresenter.class.getName()).log(Level.SEVERE, "Could not fetch users.");
                users.clear();
            }

            public void onSuccess(FetchUsersResult result) {
                users.clear();
                users.addAll(result.getUsers());
                display.setUsers(users);
                display.clearSelections();
            }
        });
    }

    public interface Display extends SwingDisplay {

        HasClickHandlers getUserListClick();

        HasDoubleClickHandlers getUserListDoubleClick();

        HasClickHandlers getAddUserButton();

        public int getSelectedUserIndex();

        public void setSelectedUser(User selectedUser);

        public void setUsers(List<User> users);

        public void clearSelections();

        public void setSelection(int index);
    }
}
